<?php
class StarDict {
    private $_index_file=NULL;
    private $_data_file=NULL;
    private $_info_file=NULL;
    private $_data_fp=null;
    public function __construct($dict_dir) {
        $this->_index_file=$dict_dir.'/idx';
        $this->_data_file=$dict_dir.'/dict';
        $this->_info_file=$dict_dir.'/ifo';
        $this->_index_fp=fopen($this->_index_file,'rb');
        $this->_data_fp=fopen($this->_data_file,'rb');
    }
    public function lookup($word) {
        if ($index=$this->getIndex($word)) {
            fseek($this->_data_fp,$index[0],SEEK_SET);
            $word=array(
                    'define'=>null,
                    'examples'=>array(),
                    'pronounce'=>null
                    );
            $word['define']=fread($this->_data_fp,$index[1]);
            return $word;
        }
        return false;
    }
    private function getIndex($find_word) {
        fseek($this->_index_fp,0,SEEK_SET);
        $fp=&$this->_index_fp;
        $data_offset_len=4;
        $data_size_len=4;
        $data_len=$data_offset_len+$data_size_len;
        $possible_size=10;
        $n=0;
        while (!feof($fp)) {
            $chars='';
            $cur_len=0;
            while (!feof($fp)) {
                $pre_len=$cur_len;
                $new_char=fread($fp,$possible_size);
                if (!$new_char) {
                    return false;
                }
                $chars.=$new_char;
                $cur_len=strlen($chars);
                for ($i=$pre_len;$i<$cur_len;$i++) {
                    if ($chars[$i]==chr(0)) {
                        $word=substr($chars,0,$i);
                        fseek($fp,$i-$cur_len+1,SEEK_CUR);
                        break 2;
                    }
                }
            }
            if (strtolower($word)==strtolower($find_word)) {
                $data_offset=current(unpack('N',fread($fp,4)));
                $data_length=current(unpack('N',fread($fp,4)));
                return array($data_offset,$data_length);
            }
            fseek($fp,$data_len,SEEK_CUR);
        }
        return false;
    }
}
